//
//  Mp3Recorder.m
//  Created by bmind on 15/7/28.
//  Copyright (c) 2015年 bmind. All rights reserved.
//

#import "Mp3Recorder.h"
#import <AVFoundation/AVFoundation.h>
#import "VoiceConverter.h"
#import "lame.h"
@interface Mp3Recorder()<AVAudioRecorderDelegate>
@property (nonatomic, strong) AVAudioSession *session;
@property (nonatomic, strong) AVAudioRecorder *mp3Recorder;
@property (nonatomic, strong) AVAudioRecorder *amrRecorder;

@property (nonatomic, strong) NSString *mp3path;
@property (nonatomic, strong) NSString *amrpath;

@end

@implementation Mp3Recorder

#pragma mark - Init Methods

- (id)initWithDelegate:(id<Mp3RecorderDelegate>)delegate
{
    if (self = [super init]) {
        _delegate = delegate;
        _mp3path = [self mp3Path];
        _amrpath = [self amrPath];
    }
    return self;
}

- (void)setRecorder
{
    
    //MP3格式
    _mp3Recorder = nil;
    
    NSError *recorderSetupError = nil;
    
    NSURL *url = [NSURL fileURLWithPath:[self cacheMp3Path]];
    NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
    //录音格式 无法使用
    [settings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];
    //采样率
    [settings setValue: [NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [settings setValue :[NSNumber numberWithFloat:8000.0] forKey: AVSampleRateKey];
    //通道数
    [settings setValue :[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey];;//声音通道，这里必须为双通道 mp3
    //音频质量,采样质量
    [settings setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
    _mp3Recorder = [[AVAudioRecorder alloc] initWithURL:url
                                               settings:settings
                                                  error:&recorderSetupError];
    
    if (recorderSetupError) {
        echo(([NSString stringWithFormat:@"recorderSetupError %@",recorderSetupError]));

    }
    _mp3Recorder.meteringEnabled = YES;
    _mp3Recorder.delegate = self;
    [_mp3Recorder prepareToRecord];
    
    //转出amr
    _amrRecorder = nil;
    NSError *amrrecorderSetupError = nil;
 
    NSURL *amrUrl = [NSURL fileURLWithPath:[self cacheAmrPath]];

   NSDictionary *amrSettings=[VoiceConverter   GetAudioRecorderSettingDict];
    
    _amrRecorder = [[AVAudioRecorder alloc] initWithURL:amrUrl
                                               settings:amrSettings
                                                  error:&amrrecorderSetupError];
    
    if (amrrecorderSetupError) {
        echo(([NSString stringWithFormat:@"amrrecorderSetupError %@",amrrecorderSetupError]));

    }
    _amrRecorder.meteringEnabled = YES;
    _amrRecorder.delegate = self;
    [_amrRecorder prepareToRecord];
    
   
}

- (void)setSesstion
{
    _session = [AVAudioSession sharedInstance];
    NSError *sessionError;
    [_session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
    
    if(_session == nil)
        echo(([NSString stringWithFormat:@"Error creating session: %@", [sessionError description]]));

    else
        [_session setActive:YES error:nil];
}

#pragma mark - Public Methods
- (void)setSavePath:(NSString *)path
{
    self.mp3path = path;
    self.amrpath=path;
}

- (void)startRecord
{
    [self setSesstion];
    [self setRecorder];
    [_mp3Recorder record];
    [_amrRecorder record];

    recordTime = 0;
    playTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(countVoiceTime) userInfo:nil repeats:YES];
}


- (void)stopRecord
{
    if (playTimer) {
        double cTime = _mp3Recorder.currentTime;
        [_mp3Recorder stop];
    
         [_amrRecorder stop];
        if (cTime > 1) {
            //新的线程来处理录制音频文件转码
            [NSThread detachNewThreadSelector:@selector(audio_PCMtoMP3) toTarget:self withObject:nil];

          
        }else {
            
            [_mp3Recorder deleteRecording];
            [_amrRecorder deleteRecording];

            if ([_delegate respondsToSelector:@selector(failRecord)]) {
                [_delegate failRecord];
            }
        }
        
        [playTimer invalidate];
        playTimer = nil;
    }
}

- (void)cancelRecord
{
    if (playTimer) {
        [_mp3Recorder stop];
        [_mp3Recorder deleteRecording];
        [_amrRecorder stop];
        [_amrRecorder deleteRecording];
        [playTimer invalidate];
        playTimer = nil;
    }
}


//录音计时
- (void)countVoiceTime
{
    recordTime += 0.1;
    [_mp3Recorder updateMeters];
    const double ALPHA = 0.05;
    double peakPowerForChannel = pow(10, (0.05 * [_mp3Recorder peakPowerForChannel:0]));
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;
    if ([_delegate respondsToSelector:@selector(recording:volume:)]) {
        [_delegate recording:recordTime volume:lowPassResults];
    }
}



- (void)deleteMp3
{
    [self deleteFileWithPath:[self mp3Path]];
}

- (void)deleteCacheMp3
{
    [self deleteFileWithPath:[self cacheMp3Path]];
}
- (void)deleteAmr
{
    [self deleteFileWithPath:[self amrpath]];
}
- (void)deleteCacheAmr
{
    [self deleteFileWithPath:[self cacheAmrPath]];
}
- (void)deleteFileWithPath:(NSString *)path
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if([fileManager removeItemAtPath:path error:nil])
    {
        echo(@"删除以前的mp3文件");
    }
}


#pragma mark - Convert Utils
- (void)audio_PCMtoMP3
{
    NSString *cacheMp3Path = [self cacheMp3Path];
    NSString *cacheAmrPath =[self cacheAmrPath];
    NSString *mp3Path = [self mp3Path];
    NSString *amrPath = [self amrpath];

    
    // remove the old mp3 file
    [self deleteMp3];
    [self deleteAmr];
    //转码为amr
    [VoiceConverter ConvertWavToAmr:cacheAmrPath amrSavePath:amrPath];
    
    [self deleteCacheAmr];
    echo(([NSString stringWithFormat:@"MP3转换开始"]));

//转码为mp3
    @try {
        int read, write;
        
        FILE *pcm = fopen([cacheMp3Path cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header//去除多余的头部，不然会有咔嚓的一声噪音
        FILE *mp3 = fopen([mp3Path cStringUsingEncoding:1], "wb");  //output 输出生成的Mp3文件位置
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];
        
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 8000.0);//11025.0 // 16K采样率
        lame_set_brate(lame, 16);
        lame_set_num_channels(lame, 1);//设置1为单通道，默认为2双通道
        //lame_set_VBR(lame, vbr_default);
//        lame_set_mode(lame, 3);
//        lame_set_quality(lame, 2); /* 2=high 5 = medium 7=low 音质*/
//        lame_set_brate(lame, 128);// 压缩的比特率为128K
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);
        
        do {
            read = (int)fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            
            fwrite(mp3_buffer, write, 1, mp3);
            
        } while (read != 0);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
    }
    @catch (NSException *exception) {
        NSLog(@"%@",[exception description]);

    }
    @finally {
        [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategorySoloAmbient error: nil];
    }
    //转码结束
    //删除缓存
    [self deleteCacheMp3];
    echo(([NSString stringWithFormat:@"MP3转换结束"]));

    if (_delegate && [_delegate respondsToSelector:@selector(endConvertWithData:)]) {
        NSData *voiceData = [NSData dataWithContentsOfFile:[self mp3Path]];
        [_delegate endConvertWithData:voiceData];
    }
   
    
}

#pragma mark - Path Utils
- (NSString *)cacheMp3Path
{
    NSString *cafPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mp3cache.wav"];
    
    return cafPath;
}
- (NSString *)cacheAmrPath
{
    NSString *cafPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"amrcache.wav"];
    
    return cafPath;
}

- (NSString *)mp3Path
{
    NSString *mp3Path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"mp3sound.mp3"];
    
    return mp3Path;
}
- (NSString *)amrPath
{
    NSString *amrPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"amrsound.amr"];
    
    return amrPath;
}
@end
